package com.livra.examples.pickwebvoter.tags;

import java.io.IOException;
import java.lang.reflect.Field;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

public class SimpleTreeTag extends TagSupport {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private static final String ARRAY_NAME = "a";

    private String rootObject;
    private String captions;
    private String actionUrl;
    
    public void setRootObject(String rootObject) {
        this.rootObject = rootObject;
    }

    public void setCaptions(String captions) {
        this.captions = captions;
    }

    public void setActionUrl(String actionUrl) {
        this.actionUrl = actionUrl;
    }
    
    public String[] getArrayCaptions() {

        return this.captions.split(" ");

    }

    public int doStartTag() throws JspException {

        HttpServletRequest request = (HttpServletRequest) pageContext
                .getRequest();
        JspWriter out = pageContext.getOut();

        

        try {
            StringBuilder builder = new StringBuilder(
                    "<script>\n");
            builder.append(buildJavascriptArray(request
                    .getAttribute(this.rootObject)));
            builder.append("\nt = new Bs_Tree();\n");
            
            builder.append("\nt.imageDir   = 'js/components/tree/img/bobby/blue/';");
            builder.append("\nt.checkboxSystemImgDir = 'js/components/checkbox/img/win2k_noBorder/';");
            builder.append("\nt.initByArray(a);\n");
            builder.append("\nt.draw();\n");

            builder.append("\n</script>\n");

            out.write(builder.toString());
        } catch (IOException exc) {
            throw new JspException(exc.toString());
        } catch (IllegalArgumentException exc) {
            throw new JspException(exc.toString());
        } catch (IllegalAccessException exc) {
            throw new JspException(exc.toString());
        }
        return EVAL_PAGE;

    }

    private String buildObjectWithPath(String path, Object child)
            throws IllegalArgumentException, IllegalAccessException {
        StringBuilder arrayString = new StringBuilder();
        arrayString.append(ARRAY_NAME).append(path).append(" = new Array;\n");
        String copyActionUrl = actionUrl;
        for (Field field : child.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            Object fieldObject = field.get(child);
            if(fieldObject == null)
                continue;
            if (Iterable.class.isInstance(fieldObject)){
                arrayString.append(buildTreeChilds(fieldObject, path));
                continue;
            }
            String fieldName = field.getName();
            arrayString.append(ARRAY_NAME).append(path).append("['").append(
                    (isCaptionField(fieldName)) ? "caption" : fieldName).append("'] = '").append(
                    fieldObject.toString()).append("';\n");
            
            if(copyActionUrl != null && isParameter(fieldName) ){
                copyActionUrl = copyActionUrl.replace("@"+fieldName,fieldObject.toString());
                
            }
        }
        if(copyActionUrl != null){
            arrayString.append(ARRAY_NAME).append(path).append("['url'] = ").append(copyActionUrl).append("\n");
        }
        return arrayString.toString();

    }

    private boolean isParameter(String fieldName) {
        return actionUrl.contains("@" + fieldName);
    }

    private boolean isCaptionField(String name) {
        String[] captions = this.getArrayCaptions();
        for (int i = 0; i < captions.length; i++) {
            if (name.equalsIgnoreCase(captions[i])) {
                return true;
            }
        }
        return false;
    }

    private String buildJavascriptArray(Object object)
            throws IllegalArgumentException, IllegalAccessException {
        StringBuilder arrayString = new StringBuilder("var ")
                .append(ARRAY_NAME).append(" = new Array;\n");
        String path = "[0]";
        arrayString.append(ARRAY_NAME).append(path).append(" = new Array;\n");
        arrayString.append(ARRAY_NAME).append(path).append("['caption'] = 'root';\n");
        if (object instanceof Iterable) {
            
            arrayString.append(buildTreeChilds(object, path));

        } else {
            arrayString.append(buildObjectWithPath(path, object));

        }

        return arrayString.toString();
    }

    @SuppressWarnings("unchecked")
    private String buildTreeChilds(Object object,
            String path) throws IllegalAccessException {
        StringBuilder arrayString = new StringBuilder();
        Iterable iterable = (Iterable) object;
        int pathIndex = 0;
        arrayString.append(ARRAY_NAME).append(path).append("['children']").append(" = new Array;\n");
        for (Object parseObject : iterable) {
            
            arrayString.append(buildObjectWithPath(path + "['children']["+ pathIndex +"]",
                    parseObject));
            pathIndex++;
        }
        return arrayString.toString();
    }

    public int doEndTag() throws JspException {

        return (EVAL_PAGE);
    }

}
